/*
 * Created on 2005-4-6
 */
package com.derbysoft.core.web;

import com.derbysoft.core.Limit;
import com.derbysoft.core.LimitedList;
import com.derbysoft.core.Paginator;
import com.derbysoft.core.Sorter;
import com.opensymphony.xwork2.ActionSupport;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.Validate;
import org.apache.struts2.ServletActionContext;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;


/**
 * <code>BaseAction</code>是xwork <code>ActionSupport</code>扩展,提供一些方便的方法<br>
 *
 * @author snowway
 * @version $Id: BaseAction.java 279 2013-01-25 11:45:07Z jason $.
 */
public class BaseAction extends ActionSupport {

    private static final long serialVersionUID = -2881986774966070834L;

    /**
     * 直接得到request.getParameter(name)的值<br>
     * 需要应用服务器运行时支持
     *
     * @param name name
     * @return value
     */
    public String getParameter(String name) {
        return ServletActionContext.getRequest().getParameter(name);
    }


    public Long getLongParameter(String parameterName, boolean failIfNotFound) {
        String value = getParameter(parameterName);
        if (failIfNotFound) {
            Validate.notEmpty(value, "must set paramter:" + parameterName);
        }

        if (!StringUtils.isNumeric(value)) {
            throw new IllegalArgumentException("parameter " + parameterName + "'s value is not a numeric value");
        }
        return Long.valueOf(value);
    }

    /**
     * 直接得到request.getParameterValues(name)的值<br>
     * 需要应用服务器运行时支持
     *
     * @param name name
     * @return values
     */
    public String[] getParameterValues(String name) {
        return ServletActionContext.getRequest().getParameterValues(name);
    }


    //========================== 分页支持 ===========================================
    //分页支持
    private Paginator paginator;

    /**
     * <p/>
     * 模版页面根据pagination对象完成分页显示
     *
     * @return Returns the pagination.
     */
    public Paginator getPaginator() {
        return this.paginator;
    }

    /**
     * 当前页面
     */
    private int page = 1;

    /**
     * 显示记录数
     */
    private int count = 20;


    /**
     * 排序字段
     */
    private String sortProperty;


    /**
     * 排序类型 asc|desc
     */
    private String sortType;

    /**
     * <p/>
     * 每页显示多少记录,默认值为10
     *
     * @param count
     */
    public void setCount(int count) {
        this.count = count;
    }

    public int getCount() {
        return this.count;
    }

    /**
     * <p/>
     * 当前是第几页,默认值为1
     *
     * @param page
     */
    public void setPage(int page) {
        this.page = page;
    }


    /**
     * @return the page
     */
    public int getPage() {
        return this.page;
    }


    public String getSortProperty() {
        return sortProperty;
    }

    public void setSortProperty(String sortProperty) {
        this.sortProperty = sortProperty;
    }

    public String getSortType() {
        return sortType;
    }

    public void setSortType(String sortType) {
        this.sortType = sortType;
    }

    /**
     * 根据当前页数和显示记录数得到查询辅助对象,在paging()方法中使用
     *
     * @return QueryAssistant 查询辅助对象
     */
    protected final Limit createLimit() {
        if (page == 0) {
            return null;
        }
        int startIndex = (page - 1) * count;
        return new Limit(startIndex, count);
    }


    /**
     * 创建排序对象
     *
     * @return
     */
    protected final Sorter createSorter() {
        Sorter sorter = new Sorter();
        if (StringUtils.isNotBlank(sortProperty)) {
            if (StringUtils.equalsIgnoreCase(sortType, "asc")) {
                sorter.asc(sortProperty);
            } else {
                sorter.desc(sortProperty);
            }
        }
        return sorter;
    }

    /**
     * 在需要分页的Action.execute中调用此方法完成分页<br>
     * eg.<br>
     * <pre>
     * 	class SomeAction extends BaseAction{
     *
     * 		private XXXService service;
     *
     * 		public void setXXXService(XXXService service){
     * 			this.service = service;
     *         }
     *
     *
     * 		public String execute() throws Exception{
     * 			paging(service.findBySomething(...,getQueryAssistant()));
     * 			return SUCCESS;
     *      }
     *  }
     *  当Action执行后,Pagination对象生成,此时一些模板引擎(如:freemarker,velocity)可以通过Pagination对象完成分页
     * </pre>
     */
    protected void paging(LimitedList<?> limitedList) {
        if (limitedList == null) {
            this.paginator = new Paginator(this.count, 0);
        } else {
            this.paginator = new Paginator(this.count, this.page, limitedList.getTotalcount());
        }
    }


    /**
     * @return Params
     */
    public Params getParams() {
        return new Params(ServletActionContext.getRequest());
    }

    /**
     * 某些情况下需要传递参数到action，但action对这些参数不感兴趣，可能只是将这些参数导向到相关的view
     * <p/>
     * usage:<br>
     * if the get url is:http://localhost:8080/Base.action?id=1&name=2<br>
     * you can access the id and name variable in the view like below:<br>
     * ${params.id},${params.name}<br>
     *
     * @author snowway
     */
    @SuppressWarnings("unchecked")
    public static class Params extends HashMap {
        /**
         *
         */
        private static final long serialVersionUID = 6124274561487102384L;

        private HttpServletRequest request;

        public Params(HttpServletRequest request) {
            this.request = request;
        }


        public String get(Object key) {
            if (this.request != null) {
                return request.getParameter(key.toString());
            }
            throw new IllegalStateException("can not invoke in non web environment!");
        }

    }
}
